﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Drawing.Imaging;
using Emgu.CV;
using Emgu.Util;
using Emgu.CV.Structure;
using Emgu.CV.CvEnum;
using System.Diagnostics;

namespace CVsift
{
    public partial class Form4 : Form
    {

#region 变量
        Contour<Point> image_contours;
        Contour<Point> reference_contours;
        Image<Rgb, Byte> src;
        Image img0 = Image.FromFile("D:/test/3.jpg");
#endregion

        public Form4()
        {
            this.MaximizeBox = false;
            InitializeComponent();
            pictureBox2.Image = img0;
        }

        private void 打开标准图像ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            OpenFileDialog ofd = new OpenFileDialog();
            ofd.Filter = "Image|*.bmp;*.png;*.jpg;*.jpeg";
            ofd.FilterIndex = 1;
            if (ofd.ShowDialog()!=DialogResult.OK)
            {
                return;
            }
                Image<Rgb,Byte> img=new Image<Rgb,Byte>(ofd.FileName);
                pictureBox1.Image = img.ToBitmap();
                src = img;    
        }

        private void 退出ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Application.Exit();
        }

        /// <summary>
        /// 转换成灰度图
        /// </summary>
        public void ToGray()
        {

            Image<Gray, Byte> imageGrayscale = src.Convert<Gray, Byte>();
            if (pictureBox1.Image != null)
            {
                pictureBox1.Image.Dispose();
                pictureBox1.Image = null;
            }
            pictureBox1.Image = imageGrayscale.ToBitmap();
        }


        /// <summary>
        /// 图像二值化
        /// </summary>
        public void ToBit()
        {
            Image<Gray, Byte> imageGrayscale = src.Convert<Gray, Byte>();
            Image<Gray, Byte> imageThreshold = imageGrayscale.ThresholdBinary(new Gray(200), new Gray(255));
            if (pictureBox1.Image != null)
            {
                pictureBox1.Image.Dispose();
                pictureBox1.Image = null;
            }
            pictureBox1.Image = imageThreshold.ToBitmap();
        }


        /// <summary>
        /// 求图像轮廓
        /// </summary>
        public void contour()
        {
            /*
            Image<Gray, Byte> imageGrayscale = src.Convert<Gray, Byte>();
            Image<Gray, Byte> imageThreshold = imageGrayscale.ThresholdBinary(new Gray(200), new Gray(255));
            Image<Gray, Byte> imagecanny = imageThreshold.Canny(new Gray(10), new Gray(150));
            Image<Bgr, Byte> imageResult=new Image<Bgr, Byte>(imagecanny.Size) ;
            image_contours = imagecanny.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE,
                 Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL);
            for(;image_contours!=null;image_contours=image_contours.HNext)
            {
                if (image_contours.Total > 200)
                CvInvoke.cvDrawContours(imageResult, image_contours,new MCvScalar(255, 255, 255),
                    new MCvScalar(255, 255, 255), 0, 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, new Point(0, 0));     
            }
                if (pictureBox1.Image != null)
                {
                    pictureBox1.Image.Dispose();
                    pictureBox1.Image = null;
                }
                pictureBox1.Image = imageResult.ToBitmap();
             * */
        }


        /// <summary>
        /// canny算子求图像边缘
        /// </summary>
        public void canny()
        {
            /*
            Image<Gray, Byte> imageGrayscale = src.Convert<Gray, Byte>();

            Image<Gray, Byte> imageThreshold = imageGrayscale.ThresholdBinary(new Gray(200), new Gray(255));

            Image<Gray, Byte> imagecanny = imageThreshold.Canny(new Gray(10), new Gray(150));

            if (pictureBox1.Image != null)
            {
                pictureBox1.Image.Dispose();
                pictureBox1.Image = null;
            }
            pictureBox1.Image = imagecanny.ToBitmap();
             * */
        }

        private void 转换成灰度图ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ToGray(); 
        }
        
        private void 二值化ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            ToBit();
        }
        
        private void 求边缘ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            canny();
        }
        
        private void 求轮廓ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            contour();
        }

        private void Gray_CheckedChanged(object sender, EventArgs e)
        {
            if (Gray.Checked) ToGray();
        }

        private void Binary_CheckedChanged(object sender, EventArgs e)
        {
            if (Binary.Checked) ToBit();
        }

        private void checkBox_canny_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox_canny.Checked) canny();
        }

        private void checkBox_Contour_CheckedChanged(object sender, EventArgs e)
        {
            if (checkBox_Contour.Checked) contour();
            
        }


        /// <summary>
        /// 处理标准图像
        /// </summary>
        public void DelImg()
        {
            /*
            Image<Bgr, Byte> imageSource = new Image<Bgr, byte>((Bitmap)pictureBox2.Image);
            Image<Gray, Byte> imageGrayscale = imageSource.Convert<Gray, Byte>();
            Image<Gray, Byte> imageThreshold = imageGrayscale.ThresholdBinary(new Gray(200), new Gray(255));
            Image<Gray, Byte> imagecanny = imageThreshold.Canny(new Gray(10), new Gray(150));
            Image<Gray, Byte> imageResult = new Image<Gray, Byte>(imagecanny.Size);
            reference_contours = imagecanny.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE,
                 Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL);
            
            for (; reference_contours != null;reference_contours=reference_contours.HNext )
            {
                if (reference_contours.Total > 200)
                    CvInvoke.cvDrawContours(imageResult, reference_contours, new MCvScalar(255, 255, 255),
                           new MCvScalar(255, 255, 255), 0, 1, Emgu.CV.CvEnum.LINE_TYPE.EIGHT_CONNECTED, new Point(0, 0));     
            }
             
            if (pictureBox2.Image != null)
            {
                pictureBox2.Image.Dispose();
                pictureBox2.Image = null;
            }
            pictureBox2.Image = imageResult.ToBitmap();
            reference_contours = imagecanny.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_NONE,
                 Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL);
             * */
            
        }

        private void 标准图像处理ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            DelImg();
        }


        /// <summary>
        /// 轮廓匹配
        /// </summary>
        /// <returns></returns>
        public double match()
        {           
            using (MemStorage storage = new MemStorage())
            {
                Image<Gray, Byte> imageGrayscale1 = src.Convert<Gray, Byte>();
                Image<Gray, Byte> imageThreshold1 = imageGrayscale1.ThresholdBinary(new Gray(200), new Gray(255));
                image_contours = imageThreshold1.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
                 Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL,storage);
                Image<Bgr, Byte> imageSource = new Image<Bgr, byte>((Bitmap)pictureBox2.Image);
                Image<Gray, Byte> imageGrayscale = imageSource.Convert<Gray, Byte>();
                Image<Gray, Byte> imageThreshold = imageGrayscale.ThresholdBinary(new Gray(200), new Gray(255));
               
                reference_contours = imageThreshold.FindContours(Emgu.CV.CvEnum.CHAIN_APPROX_METHOD.CV_CHAIN_APPROX_SIMPLE,
                     Emgu.CV.CvEnum.RETR_TYPE.CV_RETR_EXTERNAL,storage);
           
                double a;        
                a = CvInvoke.cvMatchShapes(imageThreshold, imageThreshold1, CONTOURS_MATCH_TYPE.CV_CONTOUR_MATCH_I1, 0);
                return a;
            }
        }


        private void 图像匹配ToolStripMenuItem_Click(object sender, EventArgs e)
        {
            Stopwatch sw = new Stopwatch();
            sw.Start();
            DelImg();
            sw.Stop();
            double t = sw.Elapsed.TotalMilliseconds;
            this.textBox1.Text = t.ToString() + "ms";
            double b=match();
            this.textBox2.Text = b.ToString();
        }
    }
}
